package com.sailors.common.task.provider.infra.design.ddd;

import java.util.function.Supplier;

/**
 * 预留lazy模型提高 DDD 领域模型创建性能，防止模型过大性能慢，聚合模型提升更为明显。
 *
 * 例如： 运营停止砍一刀活动，那我只需要关注基本信息的状态，不需要关注具体其他值对象。 常规创建领域模型会把值对象直接赋值出来，
 * 懒加载模式全部不预先创建，需要的时候（get）的时候才创建。
 *
 * @description:
 * @author: cyj
 * @date 2023 -04-17 18:11:21
 */
public final class LazyObject<T> {

    /**
     * Lazy obj 具体的lazy对象
     */
    private T lazyObj;

    /**
     * Supplier 返回一个对象为lazyObj
     */
    private Supplier<T> supplier;

    /**
     * Lock
     */
    private final Object lock = new Object();

    /**
     * Lazy object
     *
     * @param supplier supplier
     */
    public LazyObject(Supplier<T> supplier) {
        this.supplier = supplier;
    }

    /**
     * Gets lazy model *
     *
     * @return the lazy model
     */
    public T get() {
        if (null == this.lazyObj) {
            synchronized (this.lock) {
                if (null == this.lazyObj) {
                    this.lazyObj = supplier.get();
                }
            }
        }
        return this.lazyObj;
    }
}
